package terminal.gui;

import java.util.UUID;

import javax.smartcardio.CardException;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jboss.remoting.CannotConnectException;
import org.jboss.remoting.ServerInvoker.InvalidStateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import terminal.communication.CommunicationService;
import terminal.utils.BeanProvider;
import core.cards.election.gui.ElectionFrontend;
import core.cards.election.model.ElectionBackend;
import core.smartCardReader.SmartCardReaderService;
import core.utils.ConfigPropertiesHolder;
import core.utils.Converter;
import core.utils.Property;

@Component
public class MainWindow {
	private static final Logger LOGGER = LoggerFactory.getLogger(MainWindow.class);

	private SmartCardReaderService smartCardReaderService = BeanProvider.smartCardReaderService();
	private CommunicationService communicationService = BeanProvider.communicationService();

	protected Shell shlMain;

	private StackLayout mainStackLayout;

	private Composite loginCmp;
	private Composite votingCmp;

	public static boolean isInDebugMode() {
		return ConfigPropertiesHolder.getInstance().getProperty(Property.DEBUG_STATE).equalsIgnoreCase("true");
	}

	public MainWindow() {
		LOGGER.debug("Tworzę MainWindow");
		LOGGER.debug("Utworzono MainWindow");
	}

	public Boolean establishConnection() {
		WzdLocatorUri wzdLocatorUri = new WzdLocatorUri();

		WizardDialog wzdDlg = new WizardDialog(shlMain, wzdLocatorUri);
		wzdDlg.open();
		if (wzdDlg.getReturnCode() == IDialogConstants.OK_ID) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @wbp.parser.entryPoint Open the window.
	 */
	public void open() {
		final Display display = Display.getDefault();

		if (establishConnection() == false) {
			return;
		}

		createContents();
		shlMain.open();
		shlMain.layout();

		while (!shlMain.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		BeanProvider.communicationService().shutDown();
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		createShlMain();

		createLoginCmp();
		// createVotingCmp("");

		mainStackLayout.topControl = loginCmp;
	}

	private void createShlMain() {
		shlMain = new Shell();
		shlMain.setMinimumSize(new Point(640, 480));
		shlMain.setSize(1024, 800);
		shlMain.setLocation(5, 5);
		shlMain.setText("Daj Głos - Terminal");

		mainStackLayout = new StackLayout();
		shlMain.setLayout(mainStackLayout);
	}

	private void createLoginCmp() {
		loginCmp = new Composite(shlMain, SWT.NONE);
		loginCmp.setLayout(new GridLayout(1, false));

		Button btnGetVotingCard = new Button(loginCmp, SWT.NONE);
		btnGetVotingCard.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				try {
					UUID votingToken = smartCardReaderService.getFirstVotingToken();
					if (votingToken == null) {
						MessageDialog.openInformation(shlMain, "Voting Token", "Voting Token not found.");
					} else {
						communicationService.askForElectionCard(MainWindow.this);
					}
				} catch (CardException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		GridData gd_btnGetVotingCard = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1);
		gd_btnGetVotingCard.widthHint = 225;
		gd_btnGetVotingCard.heightHint = 76;
		btnGetVotingCard.setLayoutData(gd_btnGetVotingCard);
		btnGetVotingCard.setText("Get Voting Card");
	}

	public void createVotingCmp(final String electionBackendXML) {
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				votingCmp = new Composite(shlMain, SWT.NONE);
				votingCmp.setLayout(new GridLayout(1, false));

				final ElectionBackend electionBackend = (ElectionBackend) Converter.xmlToObject(electionBackendXML);

				Composite electionCmp = new ElectionFrontend(votingCmp, electionBackend);
				electionCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

				Button btnVote = new Button(votingCmp, SWT.NONE);
				GridData gdBtnVote = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1);
				gdBtnVote.widthHint = 150;
				btnVote.setLayoutData(gdBtnVote);
				btnVote.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent event) {
						try {
							communicationService.sendVote(Converter.objectToXML(electionBackend), smartCardReaderService.getFirstVotingToken(), MainWindow.this);
							mainStackLayout.topControl = loginCmp;
							shlMain.layout();
						} catch (CardException e) {
							e.printStackTrace();
						}
					}
				});
				btnVote.setText("Vote");

				shlMain.pack();
				mainStackLayout.topControl = votingCmp;
				shlMain.layout();
			}
		});
	}

	public void displayInformationMessage(final String windowTitle, final String windowMessage) {
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				MessageDialog.openInformation(shlMain, windowTitle, windowMessage);
			}
		});
	}

	public void displayErrorMessage(final String windowTitle, final String windowMessage) {
		Display.getDefault().asyncExec(new Runnable() {
			@Override
			public void run() {
				MessageDialog.openError(shlMain, windowTitle, windowMessage);
			}
		});
	}

}
